package oo

import (
	"ai-curd/controller/response"
	"ai-curd/oo/article"
	"ai-curd/oo/primitive"
)

type Articles []Article

type Article interface {
	ID() int
	IDIsPresent(f func(v int))
	SetID(id int)

	Category() int
	CategoryIsPresent(f func(v int))
	SetCategory(v int)

	Title() string
	TitleIsPresent(f func(v string))
	SetTitle(v string)

	Content() string
	ContentIsPresent(f func(v string))
	SetContent(v string)

	Mapper() *response.Article
}

func NewArticle(category int) Article {
	switch category {
	case article.CategoryNormal:
		return &NormalArticle{}
	}

	panic("article category not exist")
}

func (oo Articles) Mapper() response.Articles {
	size := len(oo)
	respArticles := make(response.Articles, size)
	for i := 0; i < size; i++ {
		respArticles[i] = oo[i].Mapper()
	}
	return respArticles
}

type baseArticle struct {
	id       primitive.ID
	category article.Category
	title    article.Title
	content  article.Content
}

func (oo *baseArticle) ID() int {
	return oo.id.Value()
}

func (oo *baseArticle) IDIsPresent(f func(v int)) {
	oo.id.IsPresent(f)
}

func (oo *baseArticle) SetID(v int) {
	oo.id.SetValue(v)
}

func (oo *baseArticle) Category() int {
	return oo.category.Value()
}

func (oo *baseArticle) CategoryIsPresent(f func(v int)) {
	oo.category.IsPresent(f)
}

func (oo *baseArticle) SetCategory(v int) {
	oo.category.SetValue(v)
}

func (oo *baseArticle) Title() string {
	return oo.title.Value()
}

func (oo *baseArticle) TitleIsPresent(f func(v string)) {
	oo.title.IsPresent(f)
}

func (oo *baseArticle) SetTitle(v string) {
	oo.title.SetValue(v)
}

func (oo *baseArticle) Content() string {
	return oo.content.Value()
}

func (oo *baseArticle) ContentIsPresent(f func(v string)) {
	oo.content.IsPresent(f)
}

func (oo *baseArticle) SetContent(v string) {
	oo.content.SetValue(v)
}

func (oo *baseArticle) Mapper() *response.Article {
	if oo == nil {
		return nil
	}
	respArticle := new(response.Article)
	respArticle.ID = oo.id.Value()
	respArticle.Category = oo.category.Value()
	respArticle.Title = oo.title.Value()
	respArticle.Content = oo.content.Value()

	return respArticle
}

type NormalArticle struct {
	baseArticle
}
